#include <stdio.h>
#include <unistd.h>

#include <cctype>
#include <iostream>
#include <memory>

#include "muduo/base/Logging.h"
#include "muduo/net/Channel.h"
#include "muduo/net/EventLoop.h"
#include "muduo/net/InetAddress.h"
#include "muduo/net/TcpClient.h"
#include "muduo/net/TcpServer.h"
using namespace muduo;
using namespace muduo::net;
using std::string;

string PORT{"9999"};
string DOMAIN{"wangzhengjia.cn"};
std::string message = PORT + DOMAIN;
string sizeToString(const string& s)
{
  string res{"\4\1"};
  int pos = -1;
  while (std::isdigit(s[++pos]))
    ;
  int16_t port = stoi(s.substr(0, pos));
  string s_port;
  while (port) {
    s_port.push_back(char(port));
    port >>= 8;
  }
  // if(strlen(port.s_port) == 1) res.push_back('\0');

  res.append(s_port.rbegin(), s_port.rend());
  std::cout << s_port.size() << "port\n";
  res.push_back('\000');
  res.push_back('\000');
  res.push_back('\000');
  res.push_back('\001');
  res.push_back('\000');
  res += s.substr(pos);
  res.push_back('\0');
  for (auto c : res) std::cout << c << '\n';
  std::cout << res.size() << '\n';
  std::cout << res << '\n';
  return res;
}
std::weak_ptr<muduo::net::TcpConnection> g_conn;
void onConnection(const TcpConnectionPtr& conn)
{
  if (conn->connected()) {
    std::cout << "establish" << std::endl;
    // printf("onConnection(): new connection [%s] from %s\n",
    //        conn->name().c_str(),
    //        conn->peerAddress().toHostPort().c_str());
    conn->send(sizeToString(message));
    g_conn = conn;
  } else {
    printf("onConnection(): connection [%s] is down\n", conn->name().c_str());
  }
}

void onMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp receiveTime)
{
  printf("onMessage(): received %zd bytes from connection [%s] at %s\n", buf->readableBytes(),
         conn->name().c_str(), receiveTime.toFormattedString().c_str());
  conn->send("wzj");
  printf("onMessage(): [%s]\n", buf->retrieveAsString(buf->readableBytes()).c_str());
}
void onCmdRead(Timestamp)
{
//   std ::cout << "tttttttttttttttt\n";
  auto conn = g_conn.lock();
  if (conn != nullptr) {
    string s;
    getline(std::cin, s);
    std::cout << s << '\n';
    conn->send(s);
  }
}
EventLoop loop;
Channel readCmd(&loop, STDIN_FILENO);
void write_cmd()
{
  readCmd.setReadCallback(&onCmdRead);
  readCmd.enableReading();

  loop.updateChannel(&readCmd);
}
int main(int argc, char** argv)
{
  if (argc > 1) {
    message = argv[1] + DOMAIN;
  }
  write_cmd();
  std ::cout << loop.hasChannel(&readCmd) << '\n';
  InetAddress serverAddr("localhost", 9981);
  TcpClient client(&loop, serverAddr, "123");
  std::cout << message << std::endl;
  client.setConnectionCallback(onConnection);
  client.setMessageCallback(onMessage);
  client.enableRetry();
  client.connect();
  loop.loop();
}
